﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenCvSharp;
using ExpreRec.Logic.ImageAcquisition;
using System.Threading;
using ExpreRec.Logic.FaceDetection;
using ExpreRec.Logic.Util;
using ExpreRec.Logic.Expression;
using ExpreRec.Logic.Preprocessing;
using ExpreRec.Logic.Model;

namespace ExpreRec.UI
{
    public partial class CameraPictureRecognitionResultForm : Form
    {
        private IplImage currentImage; 
        private IplImage faceImage;
        private static HaarFaceDetector detector = new HaarFaceDetector();
        private static GaborExtract extractor = new GaborExtract();
        private static Classification classifier = new Classification();

        private double[] features = null;
        private CameraImageReader cameraImageReader;


        public CameraPictureRecognitionResultForm()
        {
            InitializeComponent();
            cameraImageReader = new CameraImageReader(this.pictureBoxCamera);
        }

        private void CameraPictureRecognitionResultForm_Load(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Maximized;
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            cameraImageReader.Start();

            buttonCapture.Enabled = true;
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            cameraImageReader.Stop();

            buttonCapture.Enabled = false;
            buttonFaceRecognition.Enabled = false;
            this.pictureBoxCaptured.Image = null;
            this.pictureBoxFace.Image = null;

            this.buttonGabor.Enabled = false;
            this.buttonExpressionRecognition.Enabled = false;

            this.pictureBoxGabor1.Image = null;
            this.pictureBoxGabor2.Image = null;
            this.pictureBoxGabor3.Image = null;
            this.pictureBoxGabor4.Image = null;
            listViewResult.Items.Clear();
        }

        private void CameraPictureRecognitionResultForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            cameraImageReader.Stop();
        }

        private void reloadPicture()
        {
            this.pictureBoxCaptured.Image = currentImage.ToBitmap();
            this.pictureBoxCaptured.Refresh();

            buttonFaceRecognition.Enabled = true;
            this.pictureBoxFace.Image = null;

            this.buttonGabor.Enabled = false;
            this.buttonExpressionRecognition.Enabled = false;

            this.pictureBoxGabor1.Image = null;
            this.pictureBoxGabor2.Image = null;
            this.pictureBoxGabor3.Image = null;
            this.pictureBoxGabor4.Image = null;

        }

        private void buttonCapture_Click(object sender, EventArgs e)
        {
            currentImage = cameraImageReader.GetImage();

            if (currentImage != null)
            {
                reloadPicture();
            }
        }

        private void buttonFaceRecognition_Click(object sender, EventArgs e)
        {
            if (currentImage != null)
            {
                IList<IplImage> res = detector.Detect(currentImage);

                if (res != null && res.Count != 0)
                {
                    CvSize dstSize = new CvSize(Const.GaborMaskSize, Const.GaborMaskSize);
                    faceImage = Processor.ReSize(res[0], dstSize, Interpolation.Linear);

                    this.pictureBoxFace.Image = faceImage.ToBitmap();
                    this.pictureBoxFace.Refresh();

                    this.buttonGabor.Enabled = true;
                }
                else
                {
                    MessageBox.Show("捕获的图片中没有探测到人脸！");
                }
            }
        }

        private void buttonGabor_Click(object sender, EventArgs e)
        {
            IplImage[] filteredImages;
            features = extractor.ExtractFeatures(faceImage, out filteredImages);

            this.pictureBoxGabor1.Image = filteredImages[0].ToBitmap();
            this.pictureBoxGabor1.Refresh();
            this.pictureBoxGabor2.Image = filteredImages[1].ToBitmap();
            this.pictureBoxGabor2.Refresh();
            this.pictureBoxGabor3.Image = filteredImages[2].ToBitmap();
            this.pictureBoxGabor3.Refresh();
            this.pictureBoxGabor4.Image = filteredImages[3].ToBitmap();
            this.pictureBoxGabor4.Refresh();

            this.buttonExpressionRecognition.Enabled = true;
        }

        private void buttonExpressionRecognition_Click(object sender, EventArgs e)
        {
            KeyValuePair<IList<string>, IList<GaborItem>> res = classifier.GaborKNNLoadModel();
            if (res.Key.Count == 0 || res.Value.Count == 0)
            {
                MessageBox.Show("图片库不存在，请重新进行预处理！");
            }
            else
            {
                if (Variable.KNNParamSet)
                {
                    IList<KNNItem> result = classifier.GaborKNNClassification(res.Key, res.Value, features, Variable.KNNParamDistVoteFlag, Variable.KNNParamDistR, Variable.KNNParamK);

                    listViewResult.Items.Clear();

                    double total = 0;

                    foreach (KNNItem item in result)
                    {
                        total += item.V;
                    }

                    double firstRate = -1;

                    foreach (KNNItem item in result)
                    {
                        double rate = item.V * 100 / total;

                        if (firstRate == -1)
                            firstRate = rate;

                        ListViewItem listViewItem = new ListViewItem(item.Label);
                        listViewItem.SubItems.Add(rate.ToString() + "%");

                        listViewResult.Items.Add(listViewItem);
                    }

                    MessageBox.Show(string.Format("系统判断最后可能的表情为{0}，可能性是{1}", result[0].Label, firstRate));
                }
                else
                {
                    MessageBox.Show("KNN参数尚未设置，请先进行训练！");
                }
            }
        }

    }
}
